﻿Imports System.IO
Imports NewHeaderSystems.Archive.Types

''' <summary>
''' Parses the Advent Omgeo XML format
''' </summary>
''' <remarks></remarks>
Public Class AdventProcessor
    Inherits BaseProcessor


    Public Function Process(ByVal sourceFilePath As String, ByVal userID As Integer) As Integer

        BackgroundReporter.MessagePrefix = Path.GetFileName(sourceFilePath)
        Dim reader As New StreamReader(New FileStream(sourceFilePath, FileMode.Open, FileAccess.Read))
        Dim line = reader.ReadLine
        Dim confirmsList As New List(Of TradeSuite)
        Do While Not line Is Nothing
            If line.Contains("<Msg MessageType") Then
                Dim tradeSuite As TradeSuite = CreateTradeSuiteRec(ParseAdventXml(line))
                BackgroundReporter.ReportProgress(tradeSuite.ToString())
                AplProcessor.FindMatch(tradeSuite)
                confirmsList.Add(tradeSuite)
            End If
            line = reader.ReadLine
        Loop
        reader.Close()
        BackgroundReporter.ReportProgress("Saving confirms...")
        Return Save(confirmsList, userID, sourceFilePath)
    End Function

    Private Shared Function ReturnXmlValue(ByRef txtLine As String, ByRef strName As String) As String
        Dim strHack As String
        Dim tmpStart, tmpLength, tmpQuote As Integer
        strHack = txtLine
        If (InStr(strHack, strName) > 0) Then
            tmpStart = InStr(strHack, strName)
            tmpQuote = InStr(tmpStart, strHack, Chr(34))
            tmpLength = InStr(tmpQuote + 1, strHack, Chr(34))
            strHack = Mid(strHack, tmpQuote + 1, (tmpLength - tmpQuote - 1))
            ReturnXmlValue = strHack
            ReturnXmlValue = Replace(ReturnXmlValue, "'", "")
            ReturnXmlValue = Trim(ReturnXmlValue)
        Else
            ReturnXmlValue = ""
        End If
    End Function

    ' Converts XML date format (YYYYMMDD) to display format (MM/DD/YYYY)
    Private Shared Function ConvertDateFormat(ByVal strField As String) As String
        Dim strMonth, strDay, strYear As String

        If strField = "" Then
            ConvertDateFormat = "        NA"
        Else
            strYear = Mid(strField, 1, 4)
            strMonth = Mid(strField, 5, 2)
            strDay = Mid(strField, 7, 2)
            ConvertDateFormat = strMonth & "/" & strDay & "/" & strYear
        End If
    End Function

    ' Formats and Right Justifies XML fields to certain lengths
    Private Shared Function FormatXmlField(ByVal strField As String, ByVal FormatLength As Integer) As String
        Dim OldLength, n As Integer

        If strField = "" Then
            FormatXmlField = ""
        Else
            OldLength = Len(strField)
        End If
        For n = 1 To (FormatLength - OldLength)
            strField = " " & strField
        Next n
        FormatXmlField = strField
    End Function

    ' Removes offending characters from string
    Private Shared Function RemoveXmlChar(ByVal strField As String) As String
        Do While (InStr(strField, "0") = 1) And (Len(strField) > 1)
            strField = Mid(strField, 2, Len(strField))
        Loop

        Return Trim(strField)
    End Function

    ' converts XML message
    Private Function ParseAdventXml(ByRef txtLine As String) As AdventData
        Dim adventData = New AdventData
        adventData.CancelIndicator = ReturnXmlValue(txtLine, "CancelIndicator=")
        adventData.DTCEligInd = ReturnXmlValue(txtLine, "DTCEligInd=")
        adventData.InsDTC = ReturnXmlValue(txtLine, "InsDTC=")
        adventData.InsDTC = RemoveXmlChar(adventData.InsDTC)
        adventData.InsName = ReturnXmlValue(txtLine, "InsName=")
        adventData.InsName = Mid(adventData.InsName, 1, 32)
        adventData.ExecutingBrokerDTCId = ReturnXmlValue(txtLine, "ExecutingBrokerDTCId=")
        adventData.ExecutingBrokerDTCId = RemoveXmlChar(adventData.ExecutingBrokerDTCId)
        adventData.ExecutingBrokerName = ReturnXmlValue(txtLine, "ExecutingBrokerName=")
        adventData.ExecutingBrokerName = Mid(adventData.ExecutingBrokerName, 1, 32)
        adventData.ExecutingBrokerAccount = ReturnXmlValue(txtLine, "ExecutingBrokerAccount=")
        adventData.ClearingBrokerDTCId = ReturnXmlValue(txtLine, "ClearingBrokerDTCId=")
        adventData.ClearingBrokerDTCId = RemoveXmlChar(adventData.ClearingBrokerDTCId)
        adventData.ClearingBrokerDTCName = ReturnXmlValue(txtLine, "ClearingBrokerDTCName=")
        adventData.ClearingBrokerDTCName = Mid(adventData.ClearingBrokerDTCName, 1, 32)
        adventData.ClearingBrokerAccount = ReturnXmlValue(txtLine, "ClearingBrokerAccount=")
        adventData.ClearingBrokerAccount = Trim(adventData.ClearingBrokerDTCId)
        adventData.ClearingBrokerName = ReturnXmlValue(txtLine, "ClearingBrokerName=")
        adventData.ClearingBrokerName = Mid(adventData.ClearingBrokerName, 1, 32)
        adventData.DeliverAgentDTCId = ReturnXmlValue(txtLine, "DeliverAgentDTCId=")
        adventData.DeliverAgentDTCId = RemoveXmlChar(adventData.DeliverAgentDTCId)
        adventData.DeliverAgentAccount = ReturnXmlValue(txtLine, "DeliverAgentAccount=")
        adventData.ReceiverAgentDTCId = ReturnXmlValue(txtLine, "ReceiverAgentDTCId=")
        adventData.ReceiverAgentDTCId = RemoveXmlChar(adventData.ReceiverAgentDTCId)
        adventData.ReceiverAgentAccount = ReturnXmlValue(txtLine, "ReceiverAgentAccount=")
        adventData.DeliverClearingAgentDTCId = ReturnXmlValue(txtLine, "DeliverClearingAgentDTCId=")
        adventData.DeliverClearingAgentDTCId = RemoveXmlChar(adventData.DeliverClearingAgentDTCId)
        adventData.ReceiverClearingAgentDTCId = ReturnXmlValue(txtLine, "ReceiverClearingAgentDTCId=")
        adventData.ReceiverClearingAgentDTCId = RemoveXmlChar(adventData.ReceiverClearingAgentDTCId)
        adventData.DTCControlNumber = ReturnXmlValue(txtLine, "DTCControlNumber=")
        adventData.TradeDate = ReturnXmlValue(txtLine, " TradeDate=")
        adventData.TradeDate = ConvertDateFormat(adventData.TradeDate)
        adventData.SettlementDate = ReturnXmlValue(txtLine, "SettlementDate=")
        adventData.SettlementDate = ConvertDateFormat(adventData.SettlementDate)
        adventData.RoleIndicator = ReturnXmlValue(txtLine, "RoleIndicator=")
        adventData.TransactionCode = ReturnXmlValue(txtLine, "TransactionCode=")
        adventData.PlaceOfTrade = ReturnXmlValue(txtLine, "PlaceOfTrade=")
        adventData.SecuritySymbol = ReturnXmlValue(txtLine, "SecuritySymbol=")
        adventData.SecurityType = ReturnXmlValue(txtLine, "SecurityType=")
        adventData.InterestRate = ReturnXmlValue(txtLine, "InterestRate=")
        adventData.MaturityDate = ReturnXmlValue(txtLine, "MaturityDate=")
        adventData.MaturityDate = ConvertDateFormat(adventData.MaturityDate)
        adventData.SecurityDescription1 = ReturnXmlValue(txtLine, "SecurityDescription1=")
        adventData.SecurityDescription2 = ReturnXmlValue(txtLine, "SecurityDescription2=")
        adventData.SecurityDescription3 = ReturnXmlValue(txtLine, "SecurityDescription3=")
        adventData.csv_515LinkedReference3 = ReturnXmlValue(txtLine, "_515LinkedReference3=")
        adventData.ConfirmDate = ReturnXmlValue(txtLine, " ConfirmDate=")
        adventData.ConfirmDate = ConvertDateFormat(adventData.ConfirmDate)
        adventData.ConfirmTime = ReturnXmlValue(txtLine, " ConfirmTime=")
        adventData.IntParty1DTCId = ReturnXmlValue(txtLine, "IntParty1DTCId=")
        adventData.Quantity = ReturnXmlValue(txtLine, " Quantity=")
        adventData.Price = ReturnXmlValue(txtLine, " Price=")
        adventData.IntParty2DTCId = ReturnXmlValue(txtLine, "IntParty2DTCId=")
        adventData.NetPrice = ReturnXmlValue(txtLine, " NetPrice=")
        adventData.PrincipalAmount = ReturnXmlValue(txtLine, " PrincipalAmount=")
        adventData.PrincipalAmount = FormatXmlField(adventData.PrincipalAmount, 18)
        adventData.ExchangeFee = ReturnXmlValue(txtLine, " ExchangeFee=")
        adventData.AccruedInterest = ReturnXmlValue(txtLine, " AccruedInterest=")
        adventData.Commission = ReturnXmlValue(txtLine, " Commission=")
        adventData.OtherFees = ReturnXmlValue(txtLine, " OtherFees=")
        adventData.TradeAmount = ReturnXmlValue(txtLine, " TradeAmount=")
        adventData.IntParty1Comment = ReturnXmlValue(txtLine, "IntParty1Comment=")
        adventData.IntParty2Comment = ReturnXmlValue(txtLine, "IntParty2Comment=")
        adventData.AccountFoundInd = ReturnXmlValue(txtLine, " AccountFoundInd=")
        adventData.AffirmingParty = ReturnXmlValue(txtLine, " AffirmingParty=")
        adventData.AffirmPartyAltDesg = ReturnXmlValue(txtLine, " AffirmPartyAltDesg=")
        adventData.AgentName = ReturnXmlValue(txtLine, " AgentName=")
        adventData.BrokSettleLocation = ReturnXmlValue(txtLine, " BrokSettleLocation=")
        adventData.ClearingAgentName = ReturnXmlValue(txtLine, " ClearingAgentName=")
        adventData.CommissionISOCode = ReturnXmlValue(txtLine, " CommissionISOCode=")
        adventData.DTCDate = ReturnXmlValue(txtLine, " DTCDate=")
        adventData.DTCSettleOption = ReturnXmlValue(txtLine, " DTCSettleOption=")
        adventData.DTCTime = ReturnXmlValue(txtLine, " DTCTime=")
        adventData.EligReasonCode1 = ReturnXmlValue(txtLine, " EligReasonCode1=")
        adventData.ExchangeFeeISOCode = ReturnXmlValue(txtLine, " ExchangeFeeISOCode=")
        adventData.InsBIC = ReturnXmlValue(txtLine, " InsBIC=")
        adventData.InsBIC2 = ReturnXmlValue(txtLine, " InsBIC2=")
        adventData.InsDTCId2 = ReturnXmlValue(txtLine, " InsDTCId2=")
        adventData.LinkedTransaction514 = ReturnXmlValue(txtLine, " LinkedTransaction514=")
        adventData.LinkedTransaction515 = ReturnXmlValue(txtLine, " LinkedTransaction515=")
        adventData.LongShortIndicator = ReturnXmlValue(txtLine, " LongShortIndicator=")
        adventData.MatchedInd = ReturnXmlValue(txtLine, " MatchedInd=")
        adventData.NetPriceISOCode = ReturnXmlValue(txtLine, " NetPriceISOCode=")
        adventData.PayMethInd = ReturnXmlValue(txtLine, " PayMethInd=")
        adventData.PriceIndicator = ReturnXmlValue(txtLine, " PriceIndicator=")
        adventData.PriceISOCode = ReturnXmlValue(txtLine, " PriceISOCode=")
        adventData.PrincipalAmountISOCode = ReturnXmlValue(txtLine, " PrincipalAmountISOCode=")
        adventData.QuantityType = ReturnXmlValue(txtLine, " QuantityType=")
        adventData.SecuritySymbolScheme = ReturnXmlValue(txtLine, " SecuritySymbolScheme=")
        adventData.SettleOptionInd = ReturnXmlValue(txtLine, " SettleOptionInd=")
        adventData.SourceDestinationISOCode = ReturnXmlValue(txtLine, " SourceDestinationISOCode=")
        adventData.TradeIndicator = ReturnXmlValue(txtLine, " TradeIndicator=")
        adventData.TrdInsProcNar1 = ReturnXmlValue(txtLine, " TrdInsProcNar1=")
        adventData.TrdInsProcNar2 = ReturnXmlValue(txtLine, " TrdInsProcNar2=")
        adventData.TrdInsProcNar3 = ReturnXmlValue(txtLine, " TrdInsProcNar3=")
        adventData.TrdInsProcNar4 = ReturnXmlValue(txtLine, " TrdInsProcNar4=")
        adventData.TrdInsProcNar5 = ReturnXmlValue(txtLine, " TrdInsProcNar5=")
        adventData.TrdInsProcNar6 = ReturnXmlValue(txtLine, " TrdInsProcNar6=")
        adventData.TrdInsProcNar7 = ReturnXmlValue(txtLine, " TrdInsProcNar7=")
        adventData.UpdateIndicator = ReturnXmlValue(txtLine, " UpdateIndicator=")

        Return adventData
    End Function

    ' creates standard TS rec for DB out of Advent XML message
    Private Function CreateTradeSuiteRec(ByVal adventData As AdventData) As TradeSuite

        Dim TSRec As New TradeSuite
        TSRec.SecurityID = adventData.SecuritySymbol
        TSRec.Side = adventData.TransactionCode
        TSRec.Units = Trim(adventData.Quantity)
        TSRec.Currency = adventData.PriceISOCode
        TSRec.Source = "ADV"   ' TS for TradeSuite; APL; ADV for Advent

        TSRec.TickerSymbol = ""   ' lookup later
        TSRec.AccountID = ""      ' lookup later

        TSRec.PricePerShare = Trim(adventData.Price)
        TSRec.TradeDate = adventData.TradeDate
        TSRec.SettlementDate = adventData.SettlementDate
        TSRec.Commission = Trim(adventData.Commission)
        TSRec.Fee = Trim(adventData.ExchangeFee)
        TSRec.NetAmount = Trim(adventData.TradeAmount)

        TSRec.ClrBkrNum = adventData.ClearingBrokerDTCId
        TSRec.ClrBkrName = adventData.ClearingBrokerName

        TSRec.RetrieveSubtype = ""
        TSRec.DTCStatus = ""
        TSRec.ConfirmType = ""
        TSRec.BkrDlrNum = adventData.ExecutingBrokerDTCId
        TSRec.BkrDlrBIC = ""
        TSRec.BkrDlrAccountNum = adventData.ExecutingBrokerAccount
        TSRec.BkrDlrName = adventData.ExecutingBrokerName
        TSRec.DTCControlNumber = adventData.DTCControlNumber
        TSRec.ControlNum = Trim(adventData.csv_515LinkedReference3)
        TSRec.OriginalBkrControlNum = ""
        TSRec.InstitutionID = adventData.InsDTC
        TSRec.InstitutionName = adventData.InsName

        If adventData.TransactionCode = "SELL" Then
            TSRec.AgtNum = adventData.DeliverAgentDTCId
            TSRec.AgtAccountNum = adventData.DeliverAgentAccount
        Else
            TSRec.AgtNum = adventData.ReceiverAgentDTCId
            TSRec.AgtAccountNum = adventData.ReceiverAgentAccount
        End If
        TSRec.AgtName = adventData.AgentName

        If adventData.TransactionCode = "SELL" Then
            TSRec.ClrAgtNum = adventData.DeliverClearingAgentDTCId
        Else
            TSRec.ClrAgtNum = adventData.ReceiverClearingAgentDTCId
        End If
        TSRec.ClrAgtName = adventData.ClearingAgentName

        TSRec.Market = adventData.PlaceOfTrade
        TSRec.AccountType = ""
        TSRec.SettlementCode = ""
        TSRec.SettlementLocation = adventData.BrokSettleLocation
        TSRec.Role = adventData.RoleIndicator
        TSRec.SecurityIndicator = ""
        TSRec.ExpSecurityType = adventData.SecurityType
        TSRec.SecurityDescription = Replace(adventData.SecurityDescription1, "'", "")
        TSRec.SecurityDescription2 = adventData.SecurityDescription2
        TSRec.SecurityDescription3 = adventData.SecurityDescription3
        TSRec.NetPrice = Trim(adventData.NetPrice)
        TSRec.Principal = adventData.PrincipalAmount
        TSRec.Reg_Shp = ""                                                ' APL only
        TSRec.Taxes = ""                                                  ' APL only
        TSRec.AccruedInterest = Trim(adventData.AccruedInterest)
        TSRec.OtherCharges = Trim(adventData.OtherFees)
        TSRec.SpecialInstr1 = adventData.TrdInsProcNar1
        TSRec.SpecialInstr2 = adventData.TrdInsProcNar2
        TSRec.SpecialInstr3 = adventData.TrdInsProcNar3
        TSRec.SpecialInstr4 = adventData.TrdInsProcNar4
        TSRec.SpecialInstr5 = adventData.TrdInsProcNar5
        TSRec.InterestedParty1 = adventData.IntParty1Comment
        TSRec.InterestedParty1Name = adventData.IntParty1DTCId
        TSRec.InterestedParty2 = adventData.IntParty2Comment
        TSRec.InterestedParty2Name = adventData.IntParty2DTCId
        TSRec.ActivityDate = adventData.ConfirmDate
        TSRec.ActivityTime = adventData.ConfirmTime
        If Len(TSRec.ActivityTime) = 6 Then
            TSRec.ActivityTime = Mid(TSRec.ActivityTime, 1, 2) & ":" & Mid(TSRec.ActivityTime, 3, 2) & _
            ":" & Mid(TSRec.ActivityTime, 5, 2)
        End If
        TSRec.ProcessDate = ""
        TSRec.ProcessTime = ""
        TSRec.AccrBegin = ""
        TSRec.AccrEnd = ""
        TSRec.HeadingLine = ""
        TSRec.AffirmStatus = "AFFIRM BY 12:00 PM EST"
        TSRec.EligIndicator = adventData.DTCEligInd
        TSRec.CancelIndicator = adventData.CancelIndicator

        ' construct heading line
        If TSRec.CancelIndicator = "CANC" Then
            If TSRec.EligIndicator = "DEI1" Then
                TSRec.HeadingLine = " CANCELLATION ELIGIBLE CONFIRM"
            Else
                TSRec.HeadingLine = " CANCELLATION INELIGIBLE CONFIRM"
            End If
        End If
        If (TSRec.HeadingLine = "") Then
            If TSRec.EligIndicator = "DEI1" Then
                TSRec.HeadingLine = " ELIGIBLE CONFIRM"
            Else
                TSRec.HeadingLine = " INELIGIBLE CONFIRM"
            End If
        End If
        Return TSRec
    End Function


    Private Class AdventData
        Public CancelIndicator As String
        Public DTCEligInd As String
        Public InsDTC As String
        Public InsName As String
        Public ExecutingBrokerDTCId As String
        Public ExecutingBrokerName As String
        Public ExecutingBrokerAccount As String
        Public ClearingBrokerDTCId As String
        Public ClearingBrokerDTCName As String
        Public ClearingBrokerAccount As String
        Public ClearingBrokerName As String
        Public DeliverAgentDTCId As String
        Public DeliverAgentAccount As String
        Public ReceiverAgentDTCId As String
        Public ReceiverAgentAccount As String
        Public DeliverClearingAgentDTCId As String
        Public ReceiverClearingAgentDTCId As String
        Public DTCControlNumber As String
        Public TradeDate As String
        Public SettlementDate As String
        Public RoleIndicator As String
        Public TransactionCode As String
        Public PlaceOfTrade As String
        Public SecuritySymbol As String
        Public SecurityType As String
        Public InterestRate As String
        Public MaturityDate As String
        Public SecurityDescription1 As String
        Public SecurityDescription2 As String
        Public SecurityDescription3 As String
        Public csv_515LinkedReference3 As String
        Public ConfirmDate As String
        Public ConfirmTime As String
        Public IntParty1DTCId As String
        Public Quantity As String
        Public Price As String
        Public IntParty2DTCId As String
        Public NetPrice As String
        Public PrincipalAmount As String
        Public ExchangeFee As String
        Public AccruedInterest As String
        Public Commission As String
        Public OtherFees As String
        Public TradeAmount As String
        Public IntParty1Comment As String
        Public IntParty2Comment As String
        Public AccountFoundInd As String
        Public AffirmingParty As String
        Public AffirmPartyAltDesg As String
        Public AgentName As String
        Public BrokSettleLocation As String
        Public ClearingAgentName As String
        Public CommissionISOCode As String
        Public DTCDate As String
        Public DTCSettleOption As String
        Public DTCTime As String
        Public EligReasonCode1 As String
        Public ExchangeFeeISOCode As String
        Public InsBIC As String
        Public InsBIC2 As String
        Public InsDTCId2 As String
        Public LinkedTransaction514 As String
        Public LinkedTransaction515 As String
        Public LongShortIndicator As String
        Public MatchedInd As String
        Public NetPriceISOCode As String
        Public PayMethInd As String
        Public PriceIndicator As String
        Public PriceISOCode As String
        Public PrincipalAmountISOCode As String
        Public QuantityType As String
        Public SecuritySymbolScheme As String
        Public SettleOptionInd As String
        Public SourceDestinationISOCode As String
        Public TradeIndicator As String
        Public TrdInsProcNar1 As String
        Public TrdInsProcNar2 As String
        Public TrdInsProcNar3 As String
        Public TrdInsProcNar4 As String
        Public TrdInsProcNar5 As String
        Public TrdInsProcNar6 As String
        Public TrdInsProcNar7 As String
        Public UpdateIndicator As String
    End Class
End Class
